﻿/*
===============================================================================
*文件名称(File Name) Send
*功能描述(Description):
*数据表(Tables):
*作者(Author): 赵高磊
*日期(Create Date):11/30/2015 4:11:49 PM
*修改记录(Revision History):
* V1.0.0.0 Created by 赵高磊 at 11/30/2015 4:11:49 PM
===============================================================================
*/

using Microsoft.ServiceBus.Messaging;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ServiceBus.Core
{
    /*
        ReceiveModel===>Default Peek-lock 模式
        When creating a queue or subscription client, you can specify a receive mode: Peek-lock or Receive and Delete.
        The default receive mode is PeekLock. When operating in this mode, the client sends a request to receive
        a message from Service Bus. After the client has received the message, it sends a request to complete the message.

        // 高吞吐量模式 ReceiveAndDelete,高吞吐量--数据丢失的风险较大
        When setting the receive mode to ReceiveAndDelete, both steps are combined in a single request. This reduces
        the overall number of operations, and can improve the overall message throughput. This performance gain comes
        at the risk of losing messages.
        //此外,补充说明:   Peek-lock模式 适用于客户端延迟、锁死消息的大部分场景,然而消息队列默认的就是 Peek-lock模式
        Service Bus does not support transactions for receive-and-delete operations. In addition, peek-lock semantics
        are required for any scenarios in which the client wants to defer or deadletter a message.

        问题1: 针对不同的消息,根据业务需要创建不同的队列。 如何用客户端从不同的队列接收消息,处理消息,同时控制并发性?
        问题2: 针对不同的消息,使用同一个队列,吞吐量、处理效率?
        问题3: 预测Peek-Lock模式使用会越来越慢,ServiceBus的数据存储在MsSqlserver中,在该模式下,消息被持久化到数据库中,并不会被删除

    */

    public static class SendMessageProvider
    {
        public static T ReceiveMessage<T>(string queueName = "DefaultServiceBusQueue")
        {
            try
            {
                if (!ServiceBusConfig.InitializateNpManager().QueueExists(queueName))
                {
                    ServiceBusConfig.InitializateNpManager().CreateQueue(queueName);
                }

                QueueClient client = ServiceBusConfig
                    .InitializateMsgFactory()
                    .CreateQueueClient(queueName);

                BrokeredMessage receiveMessage = client.Receive(TimeSpan.FromSeconds(5));
                if (receiveMessage != null)
                {
                    Console.WriteLine("get data from queue....analyze...");
                    var result = receiveMessage.GetBody<string>();
                    if (result != null)
                    {
                        receiveMessage.Complete();
                        return JsonConvert.DeserializeObject<T>(result);
                    }
                }
                return default(T);
            }
            catch (Exception ex)
            {
                return default(T);
            }
        }

        public static bool SendMessage<T>(T message, string queueName = "DefaultServiceBusQueue")
            where T : class
        {
            try
            {
                QueueClient client = ServiceBusConfig.InitializateMsgFactory().CreateQueueClient(queueName);
                BrokeredMessage sendMessage = new BrokeredMessage(JsonConvert.SerializeObject(message));
                client.Send(sendMessage);
            }
            catch (Exception ex)
            {
                return false;
            }
            return false;
        }

        private static bool FlushQueue(string queueName = "DefaultServiceBusQueue")
        {
            if (!ServiceBusConfig.InitializateNpManager().QueueExists(queueName))
            {
                ServiceBusConfig.InitializateNpManager().CreateQueue(queueName);
            }
            return true;
        }
    }
}